package com.duobaoyu.dby.supply.biz.client.resource.converter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.duobaoyu.dby.channel.adapter.bean.config.DictionaryConfig;
import com.duobaoyu.dby.channel.adapter.bean.logistics.ExpressInfo;
import com.duobaoyu.dby.channel.adapter.bean.logistics.LogisticsTrackInfo;
import com.duobaoyu.dby.common.core.constant.CommonConstants;
import com.duobaoyu.dby.common.core.convert.bean.BeanConvert;
import com.duobaoyu.dby.common.core.convert.bean.ReferenceMapper;
import com.duobaoyu.dby.common.core.util.StringUtil;
import com.duobaoyu.dby.common.core.validator.ValidationList;
import com.duobaoyu.dby.resource.common.admin.dto.area.*;
import com.duobaoyu.dby.resource.common.admin.dto.config.DictionaryDTO;
import com.duobaoyu.dby.resource.common.admin.dto.config.DictionaryItemDTO;
import com.duobaoyu.dby.resource.common.admin.dto.config.StateBatchDTO;
import com.duobaoyu.dby.resource.common.admin.dto.config.StateMappingDTO;
import com.duobaoyu.dby.resource.common.admin.dto.config.*;
import com.duobaoyu.dby.resource.common.admin.to.area.AreaListTO;
import com.duobaoyu.dby.resource.common.admin.to.area.AreaTO;
import com.duobaoyu.dby.resource.common.admin.to.area.AreasBindDetailTO;
import com.duobaoyu.dby.resource.common.admin.to.area.ChannelAddressTO;
import com.duobaoyu.dby.resource.common.admin.to.config.*;
import com.duobaoyu.dby.resource.common.api.dto.config.ExceptionMappingDTO;
import com.duobaoyu.dby.resource.common.api.dto.config.StateDTO;
import com.duobaoyu.dby.resource.common.api.to.config.*;
import com.duobaoyu.dby.resource.common.api.to.logistics.LogisticsNumberTO;
import com.duobaoyu.dby.resource.remote.common.dto.area.AddressDTO;
import com.duobaoyu.dby.resource.remote.common.dto.area.AddressInfoDTO;
import com.duobaoyu.dby.resource.remote.common.dto.config.TaskAsyncDTO;
import com.duobaoyu.dby.resource.remote.common.dto.config.TaskAsyncQueryPageDTO;
import com.duobaoyu.dby.resource.remote.common.to.area.AddressInfoTO;
import com.duobaoyu.dby.resource.remote.common.to.area.AddressMappingTO;
import com.duobaoyu.dby.resource.remote.common.to.config.ChannelConfigTO;
import com.duobaoyu.dby.resource.remote.common.to.config.*;
import com.duobaoyu.dby.resource.remote.common.to.logistics.ExpressInfoTO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.bo.*;
import com.duobaoyu.dby.supply.biz.client.resource.bean.dto.StateInfoDTO;
import com.duobaoyu.dby.supply.biz.client.resource.bean.dto.*;
import com.duobaoyu.dby.supply.biz.client.resource.bean.vo.*;
import com.duobaoyu.dby.supply.biz.util.ConverterUtils;
import com.duobaoyu.dby.supply.core.task.bean.BaseTaskResult;
import com.duobaoyu.dby.supply.core.task.bean.TaskAsyncParam;
import com.duobaoyu.dby.supply.core.task.bean.importtask.TaskImport;
import com.duobaoyu.dby.supply.core.task.enums.TaskTypeEnum;
import com.google.common.collect.Lists;
import org.mapstruct.Builder;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

import java.util.List;

/**
 * @author liyang
 * @version 1.0.0
 * @ClassName ResourceConverter
 * @Description resource 服务bean转换
 * @createTime 14:34:00 2023/07/11
 */
@Mapper(uses = {ReferenceMapper.class},imports = {ConverterUtils.class, TypeReference.class}, builder = @Builder(disableBuilder = true), componentModel = CommonConstants.COMPONENT_MODEL)
public interface ResourceConverter extends BeanConvert {

	/**
	 * to AddressInfoDTO
	 *
	 * @param addressInfo
	 * @return
	 */
	AddressInfoDTO toAddress(AreaInfoDTO addressInfo);

	/**
	 * to AreaInfoBO
	 *
	 * @param addressInfo
	 * @return
	 */
	AreaInfoBO toAddress(AddressInfoTO addressInfo);

	/**
	 * to AddressInfoDTO
	 *
	 * @param addressCityInfo
	 * @return
	 */
	AddressInfoDTO toAddressCity(AreaCityInfoDTO addressCityInfo);

	/**
	 * to AreaCityInfoBO
	 *
	 * @param addressInfo
	 * @return
	 */
	AreaCityInfoBO toAddressCity(AddressInfoTO addressInfo);

	/**
	 * to ChannelConfigBO
	 *
	 * @param channelConfig
	 * @return
	 */
	ChannelConfigBO toChannelConfig(ChannelConfigTO channelConfig);

	/**
	 * to ExceptionMappingDTO
	 *
	 * @param channelRule
	 * @return
	 */
	ExceptionMappingDTO toChannelExceptionRule(ChannelRuleDTO channelRule);

	/**
	 * to ChannelRuleBO
	 *
	 * @param exceptionMapping
	 * @return
	 */
	ChannelRuleBO toChannelExceptionRule(ExceptionMappingTO exceptionMapping);

	/**
	 * to DictionaryConfigBO List
	 *
	 * @param dictionaryConfigs
	 * @return
	 */
	List<DictionaryConfigBO> toDictionaryConfigs(List<DictionaryConfigTO> dictionaryConfigs);

	/**
	 * to StateDTO
	 *
	 * @param stateInfo
	 * @return
	 */
	StateDTO toStateInfo(StateInfoDTO stateInfo);

	/**
	 * to StateInfoBO
	 *
	 * @param state
	 * @return
	 */
	StateInfoBO toStateInfo(StateTO state);

	/**
	 * 物流信息转换
	 * @param expressInfo
	 * @return
	 */
	ExpressInfoBO toExpressInfo(ExpressInfoTO expressInfo);


	/**
	 * 物流信息转换
	 * @param expressInfo
	 * @return
	 */
	ExpressInfo toExpressInfo(ExpressInfoBO expressInfo);

	/**
	 * to AddressDTO
	 * @param addressQuery
	 * @return
	 */
    AddressDTO toAddress(AddressQueryDTO addressQuery);

	/**
	 * to AddressMappingVO List
	 * @param addressMappings
	 * @return
	 */
	List<AddressMappingVO> toAddressMappingList(List<AddressMappingTO> addressMappings);

	/**
	 * to AreaListDTO
	 * @param areaQueryList
	 * @return
	 */
    AreaListDTO toAreaList(AreaQueryListDTO areaQueryList);

	/**
	 * to AreaListVO Page
	 * @param data
	 * @return
	 */
	Page<AreaListVO> toAreaListPage(Page<AreaListTO> data);

	/**
	 * to ChannelAreaDTO
	 * @param channelAreas
	 * @return
	 */
	ChannelAreaDTO toChannelArea(ChannelAreasDTO channelAreas);

	/**
	 * to AreaVO List
	 * @param areaList
	 * @return
	 */
	List<AreaVO> toAreaList(List<AreaTO> areaList);

	/**
	 * to AddressBindDTO
	 * @param areaBind
	 * @return
	 */
	AddressBindDTO toAddressBind(AreaBindDTO areaBind);

	/**
	 * to AreasBindDetailDTO
	 * @param areasDetail
	 * @return
	 */
	AreasBindDetailDTO toAreasBindDetail(AreasDetailDTO areasDetail);

	/**
	 * to AreasBindDetailVO List
	 * @param areasBindDetails
	 * @return
	 */
	List<AreasBindDetailVO> toAreasBindDetailList(List<AreasBindDetailTO> areasBindDetails);

	/**
	 * to BizConfigDTO
	 * @param businessConfig
	 * @return
	 */
	BizConfigDTO toBizConfig(BusinessConfigDTO businessConfig);

	/**
	 * to BizConfigQueryDTO
	 * @param businessConfigQuery
	 * @return
	 */
	BizConfigQueryDTO toBizConfigQuery(BusinessConfigQueryDTO businessConfigQuery);

	/**
	 * to BusinessConfigInfoVO page
	 * @param bizConfigInfoPage
	 * @return
	 */
	Page<BusinessConfigInfoVO> toBusinessConfigPage(Page<BizConfigInfoTO> bizConfigInfoPage);

	/**
	 * to BusinessConfigInfoVO
	 * @param bizConfigInfo
	 * @return
	 */
	BusinessConfigInfoVO toBusinessConfig(BizConfigInfoTO bizConfigInfo);

	/**
	 * to BusinessConfigVO List
	 * @param businessConfigList
	 * @return
	 */
	List<BusinessConfigVO> toBusinessConfigList(List<BusinessConfigBO> businessConfigList);

	/**
	 * to BusinessConfigVO
	 * @param businessConfig
	 * @return
	 */
	BusinessConfigVO toBusinessConfig(BusinessConfigBO businessConfig);

	/**
	 * to ChannelConfigDTO
	 * @param channelConfig
	 * @return
	 */
	ChannelConfigDTO toChannelConfig(ChannelConfigBizDTO channelConfig);

	/**
	 * to ChannelConfigVO
	 * @param channelConfig
	 * @return
	 */
	ChannelConfigVO toChannelConfigView(ChannelConfigTO channelConfig);

	/**
	 * to ChannelConfigVO Page
	 * @param channelConfigPage
	 * @return
	 */
	Page<ChannelConfigVO> toChannelConfigPage(Page<ChannelConfigTO> channelConfigPage);

	/**
	 * to ChannelRuleConfigDTO
	 * @param channelRuleConfig
	 * @return
	 */
	ChannelRuleConfigDTO toChannelRuleConfig(ChannelRuleConfigBizDTO channelRuleConfig);

	/**
	 * to ChannelRuleConfigQueryDTO
	 * @param channelRuleConfig
	 * @return
	 */
	ChannelRuleConfigQueryDTO toChannelRuleConfig(ChannelRuleConfigQueryBizDTO channelRuleConfig);

	/**
	 * to ChannelRuleConfigVO Page
	 * @param channelRuleConfigPage
	 * @return
	 */
	Page<ChannelRuleConfigVO> toChannelRuleConfigPage(Page<ChannelRuleConfigTO> channelRuleConfigPage);

	/**
	 * to ScriptDebugDTO
	 * @param scriptDebug
	 * @return
	 */
	@Mapping(target = "params", expression = "java(ConverterUtils.parseObject(scriptDebug.getParams(), new TypeReference<Map<String,Object>>(){}))")
	ScriptDebugDTO toScriptDebug(ScriptDebugBizDTO scriptDebug);

	/**
	 * to ChannelSettingConfigVO List
	 * @param channelSettingConfigs
	 * @return
	 */
	List<ChannelSettingConfigVO> toChannelSettingConfigList(List<ChannelSettingConfigTO> channelSettingConfigs);

	/**
	 * to ChannelSettingDetailConfigVO
	 * @param channelSettingDetailConfig
	 * @return
	 */
	ChannelSettingDetailConfigVO toChannelSettingDetailConfig(ChannelSettingDetailConfigTO channelSettingDetailConfig);

	/**
	 * to ChannelSettingConfigDTO
	 * @param channelSetConfig
	 * @return
	 */
	ChannelSettingConfigDTO toChannelSettingConfig(ChannelSetConfigDTO channelSetConfig);

	/**
	 * to DictionaryDTO
	 * @param dictionary
	 * @return
	 */
	DictionaryDTO toResourceDictionary(com.duobaoyu.dby.supply.biz.client.resource.bean.dto.DictionaryDTO dictionary);

	/**
	 * to DictionaryVO Page
	 * @param dictionaryPage
	 * @return
	 */
	Page<DictionaryVO> toDictionaryPage(Page<DictionaryTO> dictionaryPage);

	/**
	 * to DictionaryItemDTO
	 * @param dictionaryItem
	 * @return
	 */
	DictionaryItemDTO toResourceDictionaryItem(com.duobaoyu.dby.supply.biz.client.resource.bean.dto.DictionaryItemDTO dictionaryItem);

	/**
	 * to DictionaryItemVO Page
	 * @param dictionaryItemPage
	 * @return
	 */
	Page<DictionaryItemVO> toDictionaryItemPage(Page<DictionaryItemTO> dictionaryItemPage);

	/**
	 * to DictionaryVO
	 * @param dictionary
	 * @return
	 */
	DictionaryVO toDictionary(DictionaryTO dictionary);

	/**
	 * to
	 * @param dictionaryConfigs
	 * @return
	 */
	List<DictionaryConfig> toDictionaryConfig(List<DictionaryConfigTO> dictionaryConfigs);

	/**
	 * to ExpressQueryDTO
	 * @param expressInfoQuery
	 * @return
	 */
	ExpressQueryDTO toExpressQuery(ExpressInfoQueryDTO expressInfoQuery);

	/**
	 * to ExpressInfoVO Page
	 * @param expressInfoPage
	 * @return
	 */
	Page<ExpressInfoVO> toExpressInfoPage(Page<ExpressInfoTO> expressInfoPage);

	/**
	 * to ExpressSaveDTO
	 * @param expressInfoSave
	 * @return
	 */
	ExpressSaveDTO toExpressSave(ExpressInfoSaveDTO expressInfoSave);

	/**
	 * to ExpressUpdateDTO
	 * @param expressInfoUpdate
	 * @return
	 */
	ExpressUpdateDTO toExpressUpdate(ExpressInfoUpdateDTO expressInfoUpdate);

	/**
	 * to ExpressStatusDTO
	 * @param expressInfoStatus
	 * @return
	 */
	ExpressStatusDTO toExpressStatus(ExpressInfoStatusDTO expressInfoStatus);

	/**
	 * to ExpressDeleteDTO
	 * @param expressInfoDelete
	 * @return
	 */
	ExpressDeleteDTO toExpressDelete(ExpressInfoDeleteDTO expressInfoDelete);

	/**
	 * to RiskStrategyConfigInfoVO List
	 * @param riskStrategyConfigInfos
	 * @return
	 */
	List<RiskStrategyConfigInfoVO> toRiskStrategyConfigInfoList(List<RiskStrategyConfigInfoTO> riskStrategyConfigInfos);

	/**
	 * to ModifyRiskStrategyConfigDTO
	 * @param riskStrategyConfig
	 * @return
	 */
	ModifyRiskStrategyConfigDTO toModifyRiskStrategyConfig(RiskStrategyConfigDTO riskStrategyConfig);


	/**
	 * to ReasonDTO
	 * @param afterSaleReason
	 * @return
	 */
	ReasonDTO toAfterSaleReason(AfterSaleReasonDTO afterSaleReason);

	/**
	 * to AfterSaleReasonVO
	 * @param afterSaleReason
	 * @return
	 */
	AfterSaleReasonVO toAfterSaleReason(AfterSaleReasonTO afterSaleReason);

	/**
	 * to AfterSaleReasonVO Page
	 * @param afterSaleReasonPage
	 * @return
	 */
	Page<AfterSaleReasonVO> toAfterSaleReasonPage(Page<AfterSaleReasonTO> afterSaleReasonPage);

	/**
	 * to TaskAsyncVO Page
	 * @param taskAsyncPage
	 * @return
	 */
	Page<TaskAsyncVO> toTaskAsyncPage(Page<TaskAsyncTO> taskAsyncPage);

	/**
	 * to TaskAsyncVO
	 * @param taskAsync
	 * @return
	 */
	TaskAsyncVO toTaskAsync(TaskAsyncTO taskAsync);

	default TaskAsyncDTO toImportTaskAsync(TaskAsyncParam taskAsyncParam, TaskImport taskImport, BaseTaskResult.SubTask subTask) {
		TaskAsyncDTO taskAsyncDTO = TaskAsyncDTO.builder()
				.parentTaskId(taskAsyncParam.getTaskId())
				.bizType(taskAsyncParam.getBizType())
				.bizTaskType(taskAsyncParam.getBizTaskType())
				.taskType(TaskTypeEnum.IMPORT_TASK.getValue())
				.build();
		TaskAsyncParam param = new TaskAsyncParam();
		param.setIzSplit(Boolean.FALSE);
		param.setTaskParam(JSON.toJSONString(TaskImport.builder()
				.operator(taskImport.getOperator())
				.sheetName(taskImport.getSheetName())
				.limitCount(taskImport.getLimitCount())
				.importFileUrl(subTask.getImportFileUrl())
				.fileName(taskImport.getFileName())
				.productInfoEnum(taskImport.getProductInfoEnum())
				.build()));
		taskAsyncDTO.setTaskParam(JSON.toJSONString(param));
		return taskAsyncDTO;
	}

	default TaskAsyncDTO toImportTaskAsync(TaskAsyncParam taskAsyncParam, Integer pageNo) {
		TaskAsyncDTO taskAsyncDTO = TaskAsyncDTO.builder()
				.parentTaskId(taskAsyncParam.getTaskId())
				.bizType(taskAsyncParam.getBizType())
				.bizTaskType(taskAsyncParam.getBizTaskType())
				.taskType(TaskTypeEnum.IMPORT_TASK.getValue())
				.build();
		TaskAsyncParam param = new TaskAsyncParam();
		param.setIzSplit(Boolean.FALSE);
		param.setTaskParam(taskAsyncParam.getTaskParam());
		param.setPageNo(pageNo);
		param.setPageSize(taskAsyncParam.getPageSize());
		taskAsyncDTO.setTaskParam(JSON.toJSONString(param));
		return taskAsyncDTO;
	}

	/**
	 * TaskAsyncTO to TaskExportVO
	 * @param taskAsync
	 * @return
	 */
	@Mappings({
			@Mapping(target = "dataTypeStr", source = "bizTaskType"),
			@Mapping(target = "status", source = "taskStatus")
	})
	TaskExportVO toTaskExport(TaskAsyncTO taskAsync);

	/**
	 * List<TaskAsyncTO> to List<TaskExportVO>
	 * @param taskAsyncs
	 * @return
	 */
	default List<TaskExportVO> toTaskExportList(List<TaskAsyncTO> taskAsyncs){
		List<TaskExportVO> taskExports = Lists.newArrayList();
		for (TaskAsyncTO taskAsync : taskAsyncs) {
			TaskExportVO exportListRes = toTaskExport(taskAsync);
			String taskResult = taskAsync.getTaskResult();
			if(StringUtil.isNotEmpty(taskResult)){
				JSONObject taskResultJsonObj = JSON.parseObject(taskResult);
				String fileUrl = taskResultJsonObj.getJSONObject("taskResult").getString("exportFileUrl");
				exportListRes.setFileUrl(fileUrl);
			}
			String taskParam = taskAsync.getTaskParam();
			if(StringUtil.isNotEmpty(taskParam)){
				JSONObject taskParamJsonObj = JSON.parseObject(taskParam);
				if(taskParamJsonObj.containsKey("taskParam")){
					JSONObject param = taskParamJsonObj.getJSONObject("taskParam");
					exportListRes.setReqParam(param.getString("searchParameter"));
				}
			}
			taskExports.add(exportListRes);
		}
		return taskExports;
	}

	/**
	 * to TaskExportVO Page
	 * @param taskAsyncPage
	 * @return
	 */
	Page<TaskExportVO> toTaskExportPage(Page<TaskAsyncTO> taskAsyncPage);

	/**
	 * to StateBatchDTO List
	 * @param stateBatchs
	 * @return
	 */
	ValidationList<StateBatchDTO> toStateBatchList(ValidationList<com.duobaoyu.dby.supply.biz.client.resource.bean.dto.StateBatchDTO> stateBatchs);

	/**
	 * to MappingBatchVO List
	 * @param mappingBatchs
	 * @return
	 */
	List<MappingBatchVO> toMappingBatchList(List<MappingBatchTO> mappingBatchs);

	/**
	 * to StateInfoDTO
	 * @param state
	 * @return
	 */
	com.duobaoyu.dby.resource.common.admin.dto.config.StateInfoDTO toStateInfo(com.duobaoyu.dby.supply.biz.client.resource.bean.dto.StateDTO state);

	/**
	 * to StateInfoVO
	 * @param stateInfo
	 * @return
	 */
	StateInfoVO toStateInfo(StateInfoTO stateInfo);

	/**
	 * to StateInfoVO Page
	 * @param stateInfoPage
	 * @return
	 */
	Page<StateInfoVO> toStateInfoPage(Page<StateInfoTO> stateInfoPage);

	/**
	 * to StateMappingDTO
	 * @param stateMapping
	 * @return
	 */
	StateMappingDTO toStateMapping(com.duobaoyu.dby.supply.biz.client.resource.bean.dto.StateMappingDTO stateMapping);

	/**
	 * to StateMappingVO
	 * @param stateMapping
	 * @return
	 */
	StateMappingVO toStateMapping(StateMappingTO stateMapping);

	/**
	 * to StateMappingVO Page
	 * @param stateMappingPage
	 * @return
	 */
	Page<StateMappingVO> toStateMappingPage(Page<StateMappingTO> stateMappingPage);

	/**
	 * to TaskAsyncQueryPageDTO
	 * @param taskAsyncQuery
	 * @return
	 */
    TaskAsyncQueryPageDTO toTaskAsyncQueryPage(TaskAsyncQueryDTO taskAsyncQuery);

	/**
	 * to AfterSaleSettingConfigBO
	 * @param afterSaleSettingConfig
	 * @return
	 */
	AfterSaleSettingConfigBO toAfterSaleSettingConfig(AfterSaleSettingConfigTO afterSaleSettingConfig);
	/**
	 * to AuditStrategyConfigBO
	 * @param auditStrategyConfig
	 * @return
	 */
	AuditStrategyConfigBO toAuditStrategyConfig(AuditStrategyConfigTO auditStrategyConfig);

	/**
	 * to OrderRuleConfigBO
	 * @param orderRuleConfig
	 * @return
	 */
	OrderRuleConfigBO toOrderRuleConfig(OrderRuleConfigTO orderRuleConfig);

	/**
	 * to PrefreightConfigBO
	 * @param prefreightConfig
	 * @return
	 */
	PrefreightConfigBO toPrefreightConfig(PrefreightConfigTO prefreightConfig);

	/**
	 * to AfterSaleReasonBO List
	 * @param afterSaleReasons
	 * @return
	 */
	List<AfterSaleReasonBO> toAfterSaleReasonList(List<AfterSaleReasonTO> afterSaleReasons);

	/**
	 * to AfterSaleReasonVO List
	 * @param afterSaleReasons
	 * @return
	 */
	List<AfterSaleReasonVO> toAfterSaleReasonVoList(List<AfterSaleReasonTO> afterSaleReasons);

	/**
	 * to MappingBO List
	 * @param mapping
	 * @return
	 */
    List<MappingBO> toMapping(List<MappingTO> mapping);

	/**
	 * to MappingVO
	 * @param mapping
	 * @return
	 */
	MappingVO toMapping(MappingTO mapping);

	/**
	 * to ChannelAddressDTO
	 * @param channelAddress
	 * @return
	 */
    ChannelAddressDTO toChannelAddress(ChannelAddressQueryDTO channelAddress);

	/**
	 * to ChannelAddressVO Page
	 * @param channelAddressPage
	 * @return
	 */
	Page<ChannelAddressVO> toChannelAddressPage(Page<ChannelAddressTO> channelAddressPage);

	/**
	 *
	 * @param data
	 * @return
	 */
	LogisticsTrackInfo toLogisticsTrackDto(LogisticsNumberTO data);
}
